"""
日志工具模块
提供统一的日志配置和管理
"""

import logging
import sys
from pathlib import Path
from logging.handlers import RotatingFileHandler
import os
from datetime import datetime


class ColoredFormatter(logging.Formatter):
    """彩色日志格式化器"""
    
    # 颜色代码
    COLORS = {
        'DEBUG': '\033[36m',      # 青色
        'INFO': '\033[32m',       # 绿色
        'WARNING': '\033[33m',    # 黄色
        'ERROR': '\033[31m',      # 红色
        'CRITICAL': '\033[35m',   # 紫色
        'RESET': '\033[0m'        # 重置
    }
    
    def format(self, record):
        """格式化日志记录"""
        # 添加颜色
        if hasattr(record, 'levelname') and record.levelname in self.COLORS:
            record.levelname = (
                f"{self.COLORS[record.levelname]}"
                f"{record.levelname}"
                f"{self.COLORS['RESET']}"
            )
        
        return super().format(record)


def setup_logger(name: str = None, 
                log_level: str = 'INFO',
                log_file: str = None,
                log_dir: str = 'logs',
                max_file_size: int = 10 * 1024 * 1024,  # 10MB
                backup_count: int = 5,
                console_output: bool = True,
                file_output: bool = True) -> logging.Logger:
    """
    设置日志记录器
    
    Args:
        name: 日志记录器名称
        log_level: 日志级别
        log_file: 日志文件名
        log_dir: 日志目录
        max_file_size: 最大文件大小
        backup_count: 备份文件数量
        console_output: 是否输出到控制台
        file_output: 是否输出到文件
        
    Returns:
        logging.Logger: 配置好的日志记录器
    """
    # 获取或创建logger
    logger = logging.getLogger(name)
    
    # 如果logger已经有handler，直接返回
    if logger.handlers:
        return logger
    
    # 设置日志级别
    logger.setLevel(getattr(logging, log_level.upper()))
    
    # 日志格式
    detailed_formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'
    )
    
    simple_formatter = ColoredFormatter(
        '%(asctime)s - %(levelname)s - %(message)s',
        datefmt='%H:%M:%S'
    )
    
    # 控制台输出
    if console_output:
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setLevel(getattr(logging, log_level.upper()))
        console_handler.setFormatter(simple_formatter)
        logger.addHandler(console_handler)
    
    # 文件输出
    if file_output:
        # 创建日志目录
        log_path = Path(log_dir)
        log_path.mkdir(parents=True, exist_ok=True)
        
        # 生成日志文件名
        if log_file is None:
            timestamp = datetime.now().strftime('%Y%m%d')
            log_file = f"bert_intent_{timestamp}.log"
        
        file_path = log_path / log_file
        
        # 创建文件处理器（支持日志轮转）
        file_handler = RotatingFileHandler(
            file_path,
            maxBytes=max_file_size,
            backupCount=backup_count,
            encoding='utf-8'
        )
        file_handler.setLevel(getattr(logging, log_level.upper()))
        file_handler.setFormatter(detailed_formatter)
        logger.addHandler(file_handler)
    
    return logger


def get_logger(name: str = None) -> logging.Logger:
    """
    获取已配置的日志记录器
    
    Args:
        name: 日志记录器名称
        
    Returns:
        logging.Logger: 日志记录器
    """
    logger = logging.getLogger(name)
    
    # 如果没有配置过，使用默认配置
    if not logger.handlers:
        logger = setup_logger(name)
    
    return logger


class LogContext:
    """日志上下文管理器"""
    
    def __init__(self, logger: logging.Logger, level: str = 'INFO'):
        """
        初始化日志上下文
        
        Args:
            logger: 日志记录器
            level: 日志级别
        """
        self.logger = logger
        self.level = getattr(logging, level.upper())
        self.start_time = None
    
    def __enter__(self):
        """进入上下文"""
        self.start_time = datetime.now()
        self.logger.log(self.level, "开始执行...")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """退出上下文"""
        if self.start_time:
            duration = datetime.now() - self.start_time
            
            if exc_type is None:
                self.logger.log(self.level, f"执行完成，耗时: {duration.total_seconds():.2f}秒")
            else:
                self.logger.error(f"执行失败，耗时: {duration.total_seconds():.2f}秒，错误: {exc_val}")
        
        return False  # 不抑制异常


def log_function_call(logger: logging.Logger = None, level: str = 'DEBUG'):
    """
    函数调用日志装饰器
    
    Args:
        logger: 日志记录器
        level: 日志级别
        
    Returns:
        装饰器函数
    """
    def decorator(func):
        def wrapper(*args, **kwargs):
            # 获取logger
            if logger is None:
                func_logger = get_logger(func.__module__)
            else:
                func_logger = logger
            
            # 记录函数调用
            func_logger.log(
                getattr(logging, level.upper()),
                f"调用函数: {func.__name__}"
            )
            
            try:
                # 执行函数
                start_time = datetime.now()
                result = func(*args, **kwargs)
                duration = datetime.now() - start_time
                
                # 记录成功
                func_logger.log(
                    getattr(logging, level.upper()),
                    f"函数 {func.__name__} 执行成功，耗时: {duration.total_seconds():.2f}秒"
                )
                
                return result
                
            except Exception as e:
                # 记录异常
                func_logger.error(f"函数 {func.__name__} 执行失败: {str(e)}")
                raise
        
        return wrapper
    return decorator


class PerformanceLogger:
    """性能日志记录器"""
    
    def __init__(self, logger: logging.Logger, operation_name: str):
        """
        初始化性能日志记录器
        
        Args:
            logger: 日志记录器
            operation_name: 操作名称
        """
        self.logger = logger
        self.operation_name = operation_name
        self.start_time = None
        self.checkpoints = []
    
    def start(self):
        """开始计时"""
        self.start_time = datetime.now()
        self.logger.info(f"开始执行: {self.operation_name}")
    
    def checkpoint(self, description: str):
        """添加检查点"""
        if self.start_time is None:
            self.logger.warning("性能监控尚未开始")
            return
        
        current_time = datetime.now()
        elapsed = current_time - self.start_time
        self.checkpoints.append((description, elapsed.total_seconds()))
        
        self.logger.debug(f"检查点 [{description}]: {elapsed.total_seconds():.2f}秒")
    
    def finish(self):
        """结束计时并输出总结"""
        if self.start_time is None:
            self.logger.warning("性能监控尚未开始")
            return
        
        total_time = (datetime.now() - self.start_time).total_seconds()
        
        self.logger.info(f"完成执行: {self.operation_name}，总耗时: {total_time:.2f}秒")
        
        # 输出检查点摘要
        if self.checkpoints:
            self.logger.info("性能检查点摘要:")
            for desc, time_elapsed in self.checkpoints:
                percentage = (time_elapsed / total_time) * 100
                self.logger.info(f"  {desc}: {time_elapsed:.2f}秒 ({percentage:.1f}%)")


def configure_root_logger(log_level: str = 'INFO', 
                         log_dir: str = 'logs',
                         enable_file_logging: bool = True):
    """
    配置根日志记录器
    
    Args:
        log_level: 日志级别
        log_dir: 日志目录
        enable_file_logging: 是否启用文件日志
    """
    # 移除现有的处理器
    root_logger = logging.getLogger()
    for handler in root_logger.handlers[:]:
        root_logger.removeHandler(handler)
    
    # 重新配置
    setup_logger(
        name=None,  # 根logger
        log_level=log_level,
        log_dir=log_dir,
        file_output=enable_file_logging
    )


# 默认配置
def init_logging():
    """初始化默认日志配置"""
    log_level = os.getenv('LOG_LEVEL', 'INFO')
    log_dir = os.getenv('LOG_DIR', 'logs')
    enable_file = os.getenv('ENABLE_FILE_LOGGING', 'true').lower() == 'true'
    
    configure_root_logger(
        log_level=log_level,
        log_dir=log_dir,
        enable_file_logging=enable_file
    )


if __name__ == "__main__":
    # 测试日志功能
    
    # 初始化日志
    init_logging()
    
    # 创建测试logger
    test_logger = setup_logger("test_module")
    
    # 测试各种日志级别
    test_logger.debug("这是调试信息")
    test_logger.info("这是信息日志")
    test_logger.warning("这是警告信息")
    test_logger.error("这是错误信息")
    
    # 测试上下文管理器
    with LogContext(test_logger, 'INFO'):
        test_logger.info("在上下文中执行操作")
        import time
        time.sleep(0.1)
    
    # 测试性能日志
    perf_logger = PerformanceLogger(test_logger, "测试操作")
    perf_logger.start()
    
    time.sleep(0.05)
    perf_logger.checkpoint("阶段1完成")
    
    time.sleep(0.03)
    perf_logger.checkpoint("阶段2完成")
    
    perf_logger.finish()
    
    # 测试装饰器
    @log_function_call(test_logger, 'INFO')
    def test_function():
        time.sleep(0.02)
        return "测试结果"
    
    result = test_function()
    test_logger.info(f"函数返回: {result}")
    
    print("\n日志模块测试完成!") 